home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 40
/
Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso
/
Aminet
/
misc
/
emu
/
TDMouse-1.1os.lha
/
TDMouse
/
TDMouse.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-10-13
|
13KB
|
514 lines
/*
// ##########################################################################
// #### ####
// #### TDMouse - A serial mouse driver for the Amiga ####
// #### =============================================== ####
// #### ####
// #### TDMouse.c ####
// #### ####
// #### Version 1.10 -- October 13, 2000 ####
// #### ####
// #### Copyright (C) 1995 Thomas Dreibholz ####
// #### Molbachweg 7 ####
// #### 51674 Wiehl/Germany ####
// #### EMail: Dreibholz@bigfoot.com ####
// #### WWW: http://www.bigfoot.com/~dreibholz ####
// #### ####
// ##########################################################################
*/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#define TITLE "\nTDMouse Version 1.10 - Copyright (C) 1997-2000 by Thomas Dreibholz"
struct IntuitionBase *IntuitionBase;
void SerRead();
void MouseEvent();
void HandleArgs();
extern FLOAT atof();
#define BIT6 (1L<<6)
#define BIT5 (1L<<5)
#define BIT4 (1L<<4)
#define BIT3 (1L<<3)
#define BIT2 (1L<<2)
#define BIT1 (1L<<1)
#define BIT0 (1L<<0)
UBYTE *TName="TDMouse 1.1, Copyright (C) 1997-2000 by Thomas Dreibholz";
UBYTE *Device="serial.device";
UWORD Unit=0;
BOOL Genius=TRUE;
BOOL MSystems=FALSE;
BOOL Share=TRUE;
WORD WriteDelay=2;
WORD TaskPri=127;
FLOAT ResX=2;
FLOAT ResY=2;
WORD PosX=0;
WORD PosY=0;
UWORD Qualifier=0;
struct IOExtSer *SerialIO;
struct IOStdReq *InputIO;
struct MsgPort *SerialPort,
*InputPort,
*ControlPort;
struct InputEvent *Event;
struct Task *ThisTask;
struct Interrupt *EInterrupt;
extern APTR IntRoutine;
LONG SerialDev=-1L,
InputDev=-1L;
ULONG ControlSignalMask;
ULONG SignalMask;
BYTE Left=0,
Right=0,
Middle=0;
void CloseAll()
{
if(ThisTask)
{
InputIO->io_Data=EInterrupt;
InputIO->io_Length=sizeof(struct Interrupt);
InputIO->io_Command=IND_REMHANDLER;
DoIO(InputIO);
}
if(SerialDev==0) CloseDevice(SerialIO);
if(SerialIO) DeleteExtIO(SerialIO);
if(SerialPort) DeletePort(SerialPort);
if(InputDev==0) CloseDevice(InputIO);
if(InputIO) DeleteExtIO(InputIO);
if(InputPort) DeletePort(InputPort);
if(ControlPort) DeletePort(ControlPort);
if(EInterrupt) FreeMem(EInterrupt,sizeof(struct Interrupt));
if(Event) FreeMem(Event,sizeof(struct InputEvent));
if(IntuitionBase) CloseLibrary(IntuitionBase);
exit(0);
}
void OpenAll()
{
register struct MsgPort *port;
register struct Message *msg;
UBYTE init;
IntuitionBase=OpenLibrary("intuition.library",0L);
if(IntuitionBase==NULL)
CloseAll();
port=FindPort(TName);
if(port!=NULL)
{
ControlPort=CreatePort(0L,0L);
if(ControlPort!=NULL)
{
msg=AllocMem(sizeof(struct Message),MEMF_CLEAR|MEMF_PUBLIC);
if(msg!=NULL)
{
msg->mn_Node.ln_Type=NT_MESSAGE;
msg->mn_ReplyPort=ControlPort;
PutMsg(port,msg);
puts("TDMouse removed.");
WaitPort(ControlPort);
FreeMem(msg,sizeof(struct Message));
CloseAll();
}
}
}
SerialPort=CreatePort(0L,0L);
InputPort=CreatePort(0L,0L);
ControlPort=CreatePort(TName,0L);
if((SerialPort==NULL)||(InputPort==NULL)||(ControlPort==NULL))
{ puts("ERROR: CreatePort()!");
CloseAll(); }
ControlSignalMask=(1L<<ControlPort->mp_SigBit);
SignalMask=ControlSignalMask+(1L<<SerialPort->mp_SigBit);
SerialIO=CreateExtIO(SerialPort,sizeof(struct IOExtSer));
if(SerialIO==NULL)
{ puts("ERROR: CreateExtIO()!");
CloseAll(); }
InputIO=CreateExtIO(InputPort,sizeof(struct IOStdReq));
if(InputIO==NULL)
{ puts("ERROR: CreateExtIO()!");
CloseAll(); }
InputDev=OpenDevice("input.device",0,InputIO,0);
if(InputDev!=0)
{
puts("ERROR: Unable to open input.device!");
CloseAll();
}
EInterrupt=AllocMem(sizeof(struct Interrupt),MEMF_CLEAR|MEMF_PUBLIC);
Event=AllocMem(sizeof(struct InputEvent),MEMF_CLEAR|MEMF_PUBLIC);
if((EInterrupt==NULL)||(Event==NULL))
{ puts("ERROR: Out of memory!");
CloseAll(); }
SerialIO->io_SerFlags=SERF_XDISABLED;
if(Share) SerialIO->io_SerFlags+=SERF_SHARED;
SerialDev=OpenDevice(Device,Unit,SerialIO,0);
if(SerialDev!=0)
{
printf("ERROR: Unable to open %s, unit %d! OpenDevice() error #%ld\n",
Device,Unit,SerialDev);
CloseAll();
}
SerialIO->io_StopBits=1;
SerialIO->io_ReadLen=7;
SerialIO->io_WriteLen=7;
SerialIO->io_Baud=1200;
SerialIO->io_RBufLen=512;
SerialIO->IOSer.io_Command=SDCMD_SETPARAMS;
DoIO(SerialIO);
if(Genius)
{
SerRead(&init);
SerRead(&init);
if(init==76)
{
puts("TDMouse: MouseSystems Mode");
MSystems=TRUE;
SerialIO->io_ReadLen=8;
SerialIO->io_WriteLen=8;
SerialIO->IOSer.io_Command=SDCMD_SETPARAMS;
DoIO(SerialIO);
}
else if(init==79)
{
puts("TDMouse: Microsoft Mode");
}
else
{
puts("TDMouse: Mouse not found/No MouseSystems mouse!");
printf("MouseID = %ld\n",init);
puts("TDMouse not installed!");
CloseAll();
}
}
EInterrupt->is_Code=&IntRoutine;
EInterrupt->is_Node.ln_Type=NT_INTERRUPT;
EInterrupt->is_Node.ln_Name="tdmouse.interrupt";
EInterrupt->is_Node.ln_Pri=52;
InputIO->io_Data=EInterrupt;
InputIO->io_Length=sizeof(struct Interrupt);
InputIO->io_Command=IND_ADDHANDLER;
DoIO(InputIO);
ThisTask=FindTask(NULL);
SetTaskPri(ThisTask,TaskPri);
printf("hres = %2.1f Mickeys/Pixel\n",ResX);
printf("vres = %2.1f Mickeys/Pixel\n",ResY);
printf("delay = %ld Mickeys\n",WriteDelay);
printf("priority = %ld\n",TaskPri);
}
void SerRead(data)
UBYTE *data;
{
REGISTER ULONG Signale;
register struct Message *msg;
SerialIO->IOSer.io_Data=data;
SerialIO->IOSer.io_Length=1L;
SerialIO->IOSer.io_Command=CMD_READ;
SendIO(SerialIO);
Signale=Wait(SignalMask);
if(Signale & ControlSignalMask)
{
msg=GetMsg(ControlPort);
if(msg!=NULL)
{
ReplyMsg(msg);
AbortIO(SerialIO);
CloseAll();
}
}
}
void main(argc,argv)
int argc;
UBYTE *argv[];
{
WORD x,y,l,r,m;
UBYTE byte;
BYTE b1,b2,b3,b4;
HandleArgs(argc,argv);
OpenAll();
start:
if(MSystems)
{
for(;;)
{
SerRead(&byte);
if((byte & 0xf8)==0x80)
{
l=r=m=0;
SerRead(&b1);
SerRead(&b2);
SerRead(&b3);
SerRead(&b4);
x=b1+b3;
y=-(b2+b4);
byte=(~byte) & 0x07;
if(byte & BIT0) r=1;
if(byte & BIT1) m=2;
if(byte & BIT2) l=4;
MouseEvent(x,y,l,r,m);
}
else if(byte==207)
{
SerRead(&byte);
if(byte==207)
SerRead(&byte);
if(byte==207)
SerRead(&byte);
if(byte==207)
SerRead(&byte);
if(byte==207)
{
MSystems=FALSE;
SerialIO->io_ReadLen=7;
SerialIO->io_WriteLen=7;
SerialIO->IOSer.io_Command=SDCMD_SETPARAMS;
DoIO(SerialIO);
goto start;
}
}
}
}
else
{
for(;;)
{
SerRead(&byte);
if(byte & BIT6)
{
l=r=m=0;
SerRead(&b1);
if(!(b1 & BIT6))
{
SerRead(&b2);
if(!(b2 & BIT6))
{
if(byte & BIT5) l=1;
if(byte & BIT4) r=1;
x=b1;
y=b2;
if(byte & BIT0) x+=64;
if(byte & BIT1) x+=128;
if(byte & BIT2) y+=64;
if(byte & BIT3) y+=128;
if(x>127) x=(256-x)*-1;
if(y>127) y=(256-y)*-1;
MouseEvent(x,y,l,r,m);
}
}
else
{
SerRead(&b2);
if((byte==76) && (b1==76) && (b2==76))
{
MSystems=TRUE;
SerialIO->io_ReadLen=8;
SerialIO->io_WriteLen=8;
SerialIO->IOSer.io_Command=SDCMD_SETPARAMS;
DoIO(SerialIO);
goto start;
}
}
}
}
}
CloseAll();
}
void HandleArgs(argc,argv)
int argc;
UBYTE *argv[];
{
register int i;
puts(TITLE);
if((argc>=1)&&(!(strcmp(argv[1],"?"))))
{
puts("\nUsage: TDMouse");
puts(" {DEVICE=device name}");
puts(" {UNIT=unit number}");
puts(" {GENIUS|NOGENIUS}");
puts(" {PORTSHARE|NOPORTSHARE}");
puts(" {RX=n} 0.2<n<64");
puts(" {RY=n} 0.2<n<64");
puts(" {TASKPRI=n} -128<=n<=127");
puts(" {EVDELAY=n} 0<=n<64");
puts("\nSee TDMouse.txt for details.\n");
exit(0);
}
for(i=1;i<argc;i++)
{
if(!(strcmp(argv[i],"GENIUS"))) Genius=TRUE;
else if(!(strcmp(argv[i],"NOGENIUS"))) Genius=FALSE;
else if(!(strcmp(argv[i],"PORTSHARE"))) Share=TRUE;
else if(!(strcmp(argv[i],"NOPORTSHARE"))) Share=FALSE;
else if(!(strncmp(argv[i],"DEVICE=",7))) Device=&argv[i][7];
else if(!(strncmp(argv[i],"UNIT=",5))) Unit=atol(&argv[i][5]);
else if(!(strncmp(argv[i],"RX=",3)))
{
ResX=atof((ULONG)argv[i]+3L);
if(ResX<0.2) ResX=0.2;
if(ResX>63.0) ResX=63.0;
}
else if(!(strncmp(argv[i],"RY=",3)))
{
ResY=atof((ULONG)argv[i]+3L);
if(ResY<0.2) ResY=0.2;
if(ResY>63.0) ResY=63.0;
}
else if(!(strncmp(argv[i],"TASKPRI=",8)))
{
TaskPri=atol((ULONG)argv[i]+8L);
if(TaskPri<-128) TaskPri=-128;
if(TaskPri>127) TaskPri=127;
}
else if(!(strncmp(argv[i],"EVDELAY=",8)))
{
WriteDelay=atol((ULONG)argv[i]+8L);
if(WriteDelay<0) WriteDelay=0;
if(WriteDelay>63) WriteDelay=63;
}
else
{
printf("Unknown argument: %s\n",argv[i]);
exit(100);
}
}
}
void MouseEvent(mx,my,l,r,m)
WORD mx,my;
BYTE l,r,m;
{
PosX+=mx;
PosY+=my;
if( ((PosX>WriteDelay) || (PosX<-WriteDelay)) ||
((PosY>WriteDelay) || (PosY<-WriteDelay)) ||
((Left!=l) || (Right!=r)) || (Middle!=m) )
{
Event->ie_SubClass=0;
Event->ie_NextEvent=0;
Event->ie_Qualifier=Qualifier;
Event->ie_Qualifier |= IEQUALIFIER_RELATIVEMOUSE;
if(l)
Event->ie_Qualifier |= IEQUALIFIER_LEFTBUTTON;
else
Event->ie_Qualifier &= (0xffff-IEQUALIFIER_LEFTBUTTON);
if(r)
Event->ie_Qualifier |= IEQUALIFIER_RBUTTON;
else
Event->ie_Qualifier &= (0xffff-IEQUALIFIER_RBUTTON);
if(m)
Event->ie_Qualifier |= IEQUALIFIER_MIDBUTTON;
else
Event->ie_Qualifier &= (0xffff-IEQUALIFIER_MIDBUTTON);
if((PosX!=0) || (PosY!=0))
{
Event->ie_Class=IECLASS_RAWMOUSE;
Event->ie_X=PosX/(UWORD)ResX;
Event->ie_Y=PosY/(UWORD)ResY;
Event->ie_Code=IECODE_NOBUTTON;
InputIO->io_Data=Event;
InputIO->io_Length=sizeof(struct InputEvent);
InputIO->io_Flags=0;
InputIO->io_Command=IND_WRITEEVENT;
CurrentTime(&Event->ie_TimeStamp.tv_secs,&Event->ie_TimeStamp.tv_micro);
DoIO(InputIO);
PosX=0;
PosY=0;
}
Event->ie_X=0;
Event->ie_Y=0;
if(Left!=l)
{
Left=l;
if(l)
Event->ie_Code=IECODE_LBUTTON;
else
Event->ie_Code=IECODE_LBUTTON|IECODE_UP_PREFIX;
CurrentTime(&Event->ie_TimeStamp.tv_secs,&Event->ie_TimeStamp.tv_micro);
DoIO(InputIO);
}
if(Right!=r)
{
Right=r;
if(r)
Event->ie_Code=IECODE_RBUTTON;
else
Event->ie_Code=IECODE_RBUTTON|IECODE_UP_PREFIX;
CurrentTime(&Event->ie_TimeStamp.tv_secs,&Event->ie_TimeStamp.tv_micro);
DoIO(InputIO);
}
if(Middle!=m)
{
Middle=m;
if(m)
Event->ie_Code=IECODE_MBUTTON;
else
Event->ie_Code=IECODE_MBUTTON|IECODE_UP_PREFIX;
CurrentTime(&Event->ie_TimeStamp.tv_secs,&Event->ie_TimeStamp.tv_micro);
DoIO(InputIO);
}
}
}
#asm
public _IntRoutine
public _geta4
_IntRoutine:
movem.l a4,-(sp)
jsr _geta4
move.w 8(a0),_Qualifier
movem.l (sp)+,a4
rts
#endasm